<template>
  <div class="chat-message group" :class="messageClass">
    <!-- 头像 -->
    <div class="avatar">
      <div v-if="isUser" class="user-avatar">
        <svg
          width="512"
          height="512"
          viewBox="0 0 512 512"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="h-full w-full"
          data-icon="User"
          aria-hidden="true"
        >
          <g clip-path="url(#clip0_5968_39205)">
            <rect width="512" height="512" rx="256" fill="#B2DDFF" />
            <circle opacity="0.68" cx="256" cy="196" r="84" fill="white" />
            <ellipse opacity="0.68" cx="256" cy="583.5" rx="266" ry="274.5" fill="white" />
          </g>
          <defs>
            <clipPath id="clip0_5968_39205">
              <rect width="512" height="512" rx="256" fill="white" />
            </clipPath>
          </defs>
        </svg>
      </div>
      <div v-else class="ai-avatar">
        <img src="@/assets/imgs/file-preview.png" alt="AI头像" class="w-full h-full" />
      </div>
    </div>

    <!-- 消息内容 -->
    <div class="message-content">
      <!-- 发送者名称 -->
      <!-- <div class="sender-name">
        {{ isUser ? '您' : 'AI助手' }}
      </div> -->

      <!-- 用户消息文件 -->
      <div v-if="messageFiles.length > 0 && isUser" class="message-files">
        <div v-for="file in messageFiles" :key="file.id" class="file-attachment">
          <img
            v-if="file.type.startsWith('image/')"
            :src="file.url"
            :alt="file.id"
            class="attached-image"
            @click="previewImage(file.url)"
          />
          <div v-else class="file-item">
            <!-- 优化的文件图标 -->
            <div class="file-icon-wrapper">
              <svg
                v-if="getFileType(file.id) === 'pdf'"
                class="file-icon pdf-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M12,0A12,12,0,0,0,0,12A12,12,0,0,0,12,24A12,12,0,0,0,24,12A12,12,0,0,0,12,0ZM9.75,6h1.5c.828,0,1.5.448,1.5,1s-.672,1-1.5,1h-1.5Zm0,3h1.5c.828,0,1.5.448,1.5,1s-.672,1-1.5,1h-1.5Zm-1.5,6V9h3c1.657,0,3,1.119,3,2.5s-1.343,2.5-3,2.5h-1.5v1.5c0,.276-.224.5-.5.5s-.5-.224-.5-.5Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'doc'"
                class="file-icon doc-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z M8,12V14H16V12H8M8,16V18H13V16H8Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'excel'"
                class="file-icon excel-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z M8,12H16V14H8V12M8,16H16V18H8V16M8,8H16V10H8V8Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'ppt'"
                class="file-icon ppt-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z M8,12H16V18H8V12M9,13V17H15V13H9Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'txt'"
                class="file-icon txt-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z M8,12V14H16V12H8M8,16V18H13V16H8Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'zip'"
                class="file-icon zip-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,17H12V15H14M14,13H12V11H14M12,9H14V7H12M14,5H12V3H14M10,2V22H14V20H16A2,2 0 0,0 18,18V6A2,2 0 0,0 16,4H14V2H10Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'audio'"
                class="file-icon audio-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'video'"
                class="file-icon video-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M17,10.5V7A1,1 0 0,0 16,6H4A1,1 0 0,0 3,7V17A1,1 0 0,0 4,18H16A1,1 0 0,0 17,17V13.5L21,17.5V6.5L17,10.5Z"
                />
              </svg>
              <svg
                v-else-if="getFileType(file.id) === 'code'"
                class="file-icon code-icon"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path
                  d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z"
                />
              </svg>
              <svg v-else class="file-icon default-icon" viewBox="0 0 24 24" fill="currentColor">
                <path
                  d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                />
              </svg>
            </div>
            <span class="file-name">{{ file.id }}</span>
          </div>
        </div>
      </div>

      <!-- 主要消息气泡 - 整合所有内容 -->
      <div class="message-bubble">
        <!-- 工作流状态 - 在气泡内部 -->
        <div v-if="workflowProcess && !isUser" class="workflow-status-section">
          <!-- 工作流默认按钮 -->
          <div class="workflow-button" @click="toggleWorkflowExpanded">
            <div class="workflow-button-content">
              <div class="workflow-icon">
                <svg
                  v-if="workflowProcess?.status === 'running'"
                  class="w-4 h-4 animate-spin"
                  fill="currentColor"
                  viewBox="0 0 20 20"
                >
                  <path
                    fill-rule="evenodd"
                    d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z"
                    clip-rule="evenodd"
                  />
                </svg>
                <svg
                  v-else-if="workflowProcess?.status === 'succeeded'"
                  class="w-4 h-4"
                  fill="currentColor"
                  viewBox="0 0 20 20"
                >
                  <path
                    fill-rule="evenodd"
                    d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
                    clip-rule="evenodd"
                  />
                </svg>
                <svg
                  v-else-if="workflowProcess?.status === 'failed'"
                  class="w-4 h-4"
                  fill="currentColor"
                  viewBox="0 0 20 20"
                >
                  <path
                    fill-rule="evenodd"
                    d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z"
                    clip-rule="evenodd"
                  />
                </svg>
                <svg v-else class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                  <path
                    fill-rule="evenodd"
                    d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
                    clip-rule="evenodd"
                  />
                </svg>
              </div>
              <span class="workflow-text">工作流</span>
              <span
                class="workflow-status-badge"
                :class="
                  workflowProcess?.status ? getWorkflowStatusClass(workflowProcess.status) : ''
                "
              >
                {{ workflowProcess?.status ? getWorkflowStatusText(workflowProcess.status) : '' }}
              </span>
              <svg
                class="workflow-chevron"
                :class="{ 'rotate-90': workflowExpanded }"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M9 5l7 7-7 7"
                />
              </svg>
            </div>
          </div>

          <!-- 工作流详细信息 - 展开时显示 -->
          <div v-if="workflowExpanded" class="workflow-details">
            <!-- 工作流追踪信息 -->
            <div
              v-if="workflowProcess?.tracing && workflowProcess.tracing.length > 0"
              class="workflow-tracing"
            >
              <div class="tracing-header">
                <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                  <path
                    fill-rule="evenodd"
                    d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z"
                    clip-rule="evenodd"
                  />
                </svg>
                <span>执行节点</span>
              </div>
              <div class="tracing-list">
                <div
                  v-for="trace in workflowProcess?.tracing?.slice(0, 4) || []"
                  :key="trace.node_id"
                  class="trace-item"
                >
                  <div class="trace-node">
                    <div class="trace-node-info">
                      <span class="node-type">{{ translateNodeType(trace.node_type) }}</span>
                      <!-- <span v-if="trace.node_id" class="node-id">{{ trace.node_id }}</span> -->
                    </div>
                    <span class="node-status" :class="getNodeStatusClass(trace.status)">
                      <svg
                        v-if="trace.status === 'running'"
                        class="w-3 h-3 animate-spin"
                        fill="currentColor"
                        viewBox="0 0 20 20"
                      >
                        <path
                          fill-rule="evenodd"
                          d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z"
                          clip-rule="evenodd"
                        />
                      </svg>
                      <svg
                        v-else-if="trace.status === 'succeeded'"
                        class="w-3 h-3"
                        fill="currentColor"
                        viewBox="0 0 20 20"
                      >
                        <path
                          fill-rule="evenodd"
                          d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
                          clip-rule="evenodd"
                        />
                      </svg>
                      <svg
                        v-else-if="trace.status === 'failed'"
                        class="w-3 h-3"
                        fill="currentColor"
                        viewBox="0 0 20 20"
                      >
                        <path
                          fill-rule="evenodd"
                          d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z"
                          clip-rule="evenodd"
                        />
                      </svg>
                      {{ trace.status || '运行中' }}
                    </span>
                  </div>
                </div>

                <!-- 不显示"查看更多"提示 -->
                <!-- <div v-if="workflowProcess.tracing && workflowProcess.tracing.length > 4" class="more-nodes-indicator">
                  <div class="more-nodes-content">
                    <svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
                      <path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
                    </svg>
                    <span class="more-text">还有 {{ workflowProcess.tracing.length - 4 }} 个节点</span>
                  </div>
                </div> -->
              </div>
            </div>
          </div>
        </div>

        <!-- AI思考过程 - 在气泡内部 -->
        <div v-if="agentThoughts && agentThoughts.length > 0" class="agent-thoughts">
          <div
            v-for="(thought, index) in agentThoughts"
            :key="thought.id || index"
            class="thought-item"
          >
            <div class="thought-header">
              <span class="thought-tool">🤔 {{ thought.tool || '思考中' }}</span>
              <span class="thought-position">步骤 {{ thought.position || index + 1 }}</span>
            </div>
            <div v-if="thought.thought" class="thought-content">
              {{ thought.thought }}
            </div>
            <div v-if="thought.tool_input" class="thought-input">
              <strong>输入:</strong> {{ thought.tool_input }}
            </div>
            <div v-if="thought.observation" class="thought-observation">
              <strong>观察:</strong> {{ thought.observation }}
            </div>
            <!-- 思考过程中的文件 -->
            <div
              v-if="thought.message_files && thought.message_files.length > 0"
              class="thought-files"
            >
              <div
                v-for="file in thought.message_files"
                :key="file.upload_file_id"
                class="thought-file"
              >
                <img
                  v-if="file.type.startsWith('image/')"
                  :src="file.url"
                  class="thought-image"
                  @click="previewImage(file.url)"
                />
                <div v-else class="file-item">
                  <span>{{ file.type }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 消息文本 - 在气泡内部 -->
        <div class="message-text" :class="{ streaming: isStreaming }">
          <div v-html="formattedContent"></div>
        </div>

        <!-- 消息结束后的文件列表 - 在气泡内部 -->
        <div v-if="responseFiles && responseFiles.length > 0" class="response-files">
          <div class="files-header">
            <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
              <path
                fill-rule="evenodd"
                d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z"
                clip-rule="evenodd"
              />
            </svg>
            <span>相关文件</span>
          </div>
          <div class="files-list">
            <div
              v-for="file in responseFiles"
              :key="file.id || file.upload_file_id"
              class="response-file-item"
            >
              <!-- 文件图标和信息 -->
              <div class="file-main-info">
                <div class="file-icon">
                  <img
                    v-if="file.type?.startsWith('image/')"
                    :src="file.url"
                    :alt="file.id || file.upload_file_id"
                    class="file-preview-image"
                    @click="previewImage(file.url)"
                  />
                  <div v-else class="file-icon-wrapper">
                    <!-- PDF 文件图标 -->
                    <svg
                      v-if="file.type?.includes('pdf') || getFileExtension(file) === 'pdf'"
                      class="file-icon pdf-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M9.5,11.5C9.5,12.3 8.8,13 8,13H7V15H5.5V9H8A2.5,2.5 0 0,1 10.5,11.5M14.5,13.5C14.5,14.6 13.6,15.5 12.5,15.5H10.5V9H12.5A4,4 0 0,1 16.5,13M18.5,10.5H17V11.5H18.5V13H17V15H15.5V9H18.5V10.5Z"
                      />
                      <path
                        d="M7,10.25H8C8.28,10.25 8.5,10.47 8.5,10.75V11.25C8.5,11.53 8.28,11.75 8,11.75H7V10.25M12,10.25H12.5C13.05,10.25 13.5,10.7 13.5,11.25V12.75C13.5,13.3 13.05,13.75 12.5,13.75H12V10.25Z"
                      />
                    </svg>

                    <!-- Word 文档图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('doc') ||
                        ['doc', 'docx'].includes(getFileExtension(file))
                      "
                      class="file-icon word-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                      />
                      <path
                        d="M15,13L14.5,15L14,13L13.5,11L13,13L12.5,15L12,13L11.5,11L11,13L10.5,15L10,13L9.5,11H8L9.5,18H10.5L11,16L11.5,18H12.5L14,11H15Z"
                      />
                    </svg>

                    <!-- Excel 文件图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('sheet') ||
                        file.type?.includes('excel') ||
                        ['xls', 'xlsx'].includes(getFileExtension(file))
                      "
                      class="file-icon excel-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                      />
                      <path
                        d="M11.5,16L10.25,14L11.5,12H10L9.25,13.5L8.5,12H7L8.25,14L7,16H8.5L9.25,14.5L10,16H11.5M14.5,12V13H16.5V12H14.5M14.5,14V15H16.5V14H14.5M14.5,16V17H16.5V16H14.5Z"
                      />
                    </svg>

                    <!-- PowerPoint 文件图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('presentation') ||
                        ['ppt', 'pptx'].includes(getFileExtension(file))
                      "
                      class="file-icon powerpoint-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                      />
                      <path
                        d="M8,11H10.5A1.5,1.5 0 0,1 12,12.5A1.5,1.5 0 0,1 10.5,14H8V16H6.5V11H8M8,12.25V12.75H10.5A.25,.25 0 0,0 10.75,12.5A.25,.25 0 0,0 10.5,12.25H8M14,11H16.5V12.25H14V13.5H16V14.75H14V16H12.5V11H14Z"
                      />
                    </svg>

                    <!-- 文本文件图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('text') ||
                        ['txt', 'md', 'rtf'].includes(getFileExtension(file))
                      "
                      class="file-icon text-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                      />
                      <path d="M7,11H17V12.5H7V11M7,13.5H17V15H7V13.5M7,16H14V17.5H7V16Z" />
                    </svg>

                    <!-- 压缩文件图标 -->
                    <svg
                      v-else-if="['zip', 'rar', '7z', 'tar', 'gz'].includes(getFileExtension(file))"
                      class="file-icon archive-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,17H12V15H14M14,13H12V11H14M12,9H14V7H12M14,5H12V3H14M10,2V22H14V20H16A2,2 0 0,0 18,18V6A2,2 0 0,0 16,4H14V2H10Z"
                      />
                    </svg>

                    <!-- 音频文件图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('audio') ||
                        ['mp3', 'wav', 'flac', 'aac', 'm4a'].includes(getFileExtension(file))
                      "
                      class="file-icon audio-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z"
                      />
                    </svg>

                    <!-- 视频文件图标 -->
                    <svg
                      v-else-if="
                        file.type?.includes('video') ||
                        ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'].includes(getFileExtension(file))
                      "
                      class="file-icon video-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M17,10.5V7A1,1 0 0,0 16,6H4A1,1 0 0,0 3,7V17A1,1 0 0,0 4,18H16A1,1 0 0,0 17,17V13.5L21,17.5V6.5L17,10.5Z"
                      />
                    </svg>

                    <!-- 代码文件图标 -->
                    <svg
                      v-else-if="
                        [
                          'js',
                          'ts',
                          'jsx',
                          'tsx',
                          'vue',
                          'html',
                          'css',
                          'scss',
                          'py',
                          'java',
                          'cpp',
                          'c',
                          'php',
                          'go',
                          'rs'
                        ].includes(getFileExtension(file))
                      "
                      class="file-icon code-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z"
                      />
                    </svg>

                    <!-- 默认文件图标 -->
                    <svg
                      v-else
                      class="file-icon default-icon"
                      viewBox="0 0 24 24"
                      fill="currentColor"
                    >
                      <path
                        d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
                      />
                    </svg>
                  </div>
                </div>
                <div class="file-details">
                  <div class="file-title">{{ getFileName(file) }}</div>
                  <div class="file-meta">
                    <span v-if="getFileExtension(file)" class="file-extension">{{
                      getFileExtension(file).toUpperCase()
                    }}</span>
                    <span v-if="getFileExtension(file) && file.size" class="file-divider">•</span>
                    <span v-if="file.size" class="file-size">{{ formatFileSize(file.size) }}</span>
                  </div>
                </div>
              </div>

              <!-- 文件操作 -->
              <div class="file-actions">
                <button
                  v-if="file.url"
                  @click="downloadFile(file)"
                  class="file-action-btn"
                  title="下载文件"
                >
                  <svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                    />
                  </svg>
                </button>
                <button
                  v-if="file.type?.startsWith('image/')"
                  @click="previewImage(file.url)"
                  class="file-action-btn"
                  title="预览图片"
                >
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
                    />
                    <path
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
                    />
                  </svg>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 引用/来源 -->
      <div v-if="citation && citation.length > 0" class="citations mb-3">
        <div class="citation-header">
          <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
            <path
              fill-rule="evenodd"
              d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z"
              clip-rule="evenodd"
            />
          </svg>
          <span>参考来源</span>
        </div>
        <div class="citation-list">
          <div v-for="cite in citation" :key="cite.segment_id" class="citation-item">
            <div class="citation-content">{{ cite.content }}</div>
            <div class="citation-meta">
              来源: {{ cite.dataset_name }} | 评分: {{ cite.score?.toFixed(2) }}
            </div>
          </div>
        </div>
      </div>

      <!-- 注释 -->
      <div v-if="annotation" class="annotation mb-3">
        <div class="annotation-header">
          <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
            <path
              d="M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7z"
            />
          </svg>
          <span>管理员注释</span>
          <span class="annotation-author">by {{ annotation?.authorName || '' }}</span>
        </div>
        <div class="annotation-content">
          {{ annotation?.logAnnotation?.content || '' }}
        </div>
      </div>

      <!-- 建议问题 -->
      <div
        v-if="suggestedQuestions && suggestedQuestions.length > 0"
        class="suggested-questions mb-3"
      >
        <div class="suggestions-header">💡 建议问题</div>
        <div class="suggestions-list">
          <button
            v-for="(question, index) in suggestedQuestions"
            :key="index"
            @click="$emit('suggest-question', question)"
            class="suggestion-btn"
          >
            {{ question }}
          </button>
        </div>
      </div>

      <!-- 时间戳和更多信息 -->
      <div class="message-meta">
        <div class="timestamp">
          {{ formatTime(timestamp) }}
        </div>
        <div v-if="more" class="more-info">
          <span v-if="more.tokens" class="token-count">{{ more.tokens }} tokens</span>
          <span v-if="more.latency" class="latency">{{ more.latency }}s</span>
        </div>
      </div>

      <!-- 反馈区域 -->
      <div v-if="showFeedbackButtons || currentFeedbackDisplay" class="feedback-section">
        <!-- 现有反馈显示 -->
        <div v-if="currentFeedbackDisplay" class="current-feedback">
          <span class="feedback-text">
            您对此回答的评价:
            <span :class="currentFeedbackDisplay?.isLike ? 'text-green-600' : 'text-red-600'">
              {{ currentFeedbackDisplay?.text || '' }}
            </span>
          </span>
        </div>

        <!-- 反馈按钮 -->
        <div v-else class="feedback-buttons">
          <button
            @click="handleDirectFeedback('like')"
            class="feedback-btn like-btn"
            :disabled="feedbackLoading"
            title="有帮助"
          >
            <svg
              v-if="!feedbackLoading"
              class="w-4 h-4"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"
              />
            </svg>
            <svg v-else class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
              <circle
                class="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                stroke-width="4"
              />
              <path
                class="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
              />
            </svg>
          </button>
          <button
            @click="handleDirectFeedback('dislike')"
            class="feedback-btn dislike-btn"
            :disabled="feedbackLoading"
            title="无帮助"
          >
            <svg
              v-if="!feedbackLoading"
              class="w-4 h-4"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.737 3h4.018c.163 0 .326.02.485.06L17 4m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10H5a2 2 0 00-2 2v6a2 2 0 002 2h2.5"
              />
            </svg>
            <svg v-else class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
              <circle
                class="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                stroke-width="4"
              />
              <path
                class="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
              />
            </svg>
          </button>
        </div>
      </div>

      <!-- 操作按钮 -->
      <div class="message-actions" v-if="!isUser">
        <button @click="copyMessage" class="action-btn" title="复制消息">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
            />
          </svg>
        </button>
        <button @click="regenerateMessage" class="action-btn" title="重新生成">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
            />
          </svg>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { ChatItem, Feedbacktype, WorkflowRunningStatus } from '@/types/app'

interface Props {
  message: ChatItem
  feedbackDisabled?: boolean
}

const props = defineProps<Props>()

const emit = defineEmits<{
  copy: [content: string]
  regenerate: [messageId: string]
  feedback: [messageId: string, feedback: Feedbacktype]
  'suggest-question': [question: string]
}>()

// 反馈相关状态
const feedbackLoading = ref(false)

// 添加工作流展开状态
const workflowExpanded = ref(false)

// 添加节点类型中文翻译功能
const translateNodeType = (nodeType: string): string => {
  const translations: Record<string, string> = {
    // 基础节点
    start: '开始节点',
    knowledge_retrieval: '知识检索',
    question_classifier: '问题分类',
    llm: '模型推理',
    code: '代码执行',
    tool: '工具调用',
    answer: '回答节点',

    end: '结束节点',
    input: '输入节点',
    output: '输出节点',

    // 数据处理节点
    data_load: '数据加载',
    data_loader: '数据加载器',
    data_preprocessing: '数据预处理',
    data_preprocess: '数据预处理',
    data_transform: '数据转换',
    data_filter: '数据过滤',
    data_validation: '数据验证',
    data_check: '数据检查',

    // 分析节点
    analysis: '数据分析',
    trend_analysis: '趋势分析',
    statistical_analysis: '统计分析',
    correlation_analysis: '相关性分析',

    // 机器学习节点
    model_training: '模型训练',
    model_train: '模型训练',
    model_validation: '模型验证',
    model_validate: '模型验证',
    model_evaluation: '模型评估',
    model_predict: '模型预测',
    model_inference: '模型推理',

    // 处理节点
    text_processing: '文本处理',
    image_processing: '图像处理',
    feature_extraction: '特征提取',
    classification: '分类处理',
    clustering: '聚类分析',

    // 输出节点
    result_output: '结果输出',
    report_generation: '报告生成',
    visualization: '数据可视化',
    export: '数据导出',

    // 控制节点
    condition: '条件判断',
    loop: '循环处理',
    parallel: '并行处理',
    merge: '数据合并',
    split: '数据分割',

    // API节点
    api_call: 'API调用',
    http_request: 'HTTP请求',
    database_query: '数据库查询',
    file_read: '文件读取',
    file_write: '文件写入'
  }

  // 如果已经是中文，直接返回
  if (/[\u4e00-\u9fa5]/.test(nodeType)) {
    return nodeType
  }

  // 转换为小写并查找翻译
  console.log('nodeType:', nodeType)
  const lowerCaseType = nodeType.toLowerCase().replace(/[-_\s]/g, '_')
  console.log('lowerCaseType:', lowerCaseType)
  return translations[lowerCaseType] || nodeType
}

// 计算属性
const isUser = computed(() => !props.message.isAnswer)

const isStreaming = computed(() => {
  // 检查消息是否正在流式传输
  return props.message.streaming === true
})

const messageClass = computed(() => ({
  'user-message': isUser.value,
  'assistant-message': !isUser.value
}))

const messageFiles = computed(() => props.message.message_files || [])
const agentThoughts = computed(() => props.message.agent_thoughts || [])
const workflowProcess = computed(() => props.message.workflowProcess)
const citation = computed(() => (props.message as any).citation || [])
const annotation = computed(() => props.message.annotation)
const suggestedQuestions = computed(() => (props.message as any).suggestedQuestions || [])
const feedback = computed(() => props.message.feedback)
const more = computed(() => (props.message as any).more)
const timestamp = computed(() => Date.now()) // 可以从 message 中获取实际时间戳

// 添加响应文件计算属性
const responseFiles = computed(() => {
  // 获取AI消息结束后的文件
  if (isUser.value) return []
  return (props.message as any).files || []
})

// 计算是否显示反馈按钮
const showFeedbackButtons = computed(() => {
  return !isUser.value && !props.feedbackDisabled && !feedback.value?.rating
})

// 计算当前反馈状态的显示
const currentFeedbackDisplay = computed(
  (): { isLike: boolean; text: string; content: string | null } | null => {
    if (!feedback.value?.rating) return null

    return {
      isLike: feedback.value.rating === 'like',
      text: feedback.value.rating === 'like' ? '👍 有帮助' : '👎 无帮助',
      content: feedback.value.content || null
    }
  }
)

const formattedContent = computed((): string => {
  // 如果是流式消息且内容为空，返回思考提示文本
  if (isStreaming.value && (!props.message.content || !props.message.content.trim())) {
    return '正在思考中...'
  }

  // 确保内容存在
  const content = props.message.content || ''
  if (!content) return ''

  // 先进行基础的Markdown渲染（除了think块）
  let formattedText = content
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.*?)\*/g, '<em>$1</em>')
    .replace(/`([^`]+)`/g, '<code>$1</code>')
    .replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>')
    .replace(/\n/g, '<br>')
    .replace(
      /\[([^\]]+)\]\(([^)]+)\)/g,
      '<a href="' +
        import.meta.env.VITE_API_DOWNLOAD_URL +
        '$2" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:underline">$1</a>'
    )

  // 最后处理 <think></think> 标签，将其转换为折叠的markdown块
  formattedText = formattedText.replace(/<think>([\s\S]*?)<\/think>/g, (match, thinkContent) => {
    // 清理思考内容中的多余空白和换行，并还原<br>为换行符
    const cleanThinkContent = thinkContent.replace(/<br>/g, '\n').trim()

    if (!cleanThinkContent) return ''

    // 生成唯一ID用于折叠功能
    const collapseId = `think-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`

    return `<details class="think-collapse" style="margin: 10px 0; border: 1px solid #e5e7eb; border-radius: 6px; overflow: hidden;">
  <summary style="background: #f8fafc; padding: 8px 12px; cursor: pointer; font-weight: 500; color: #374151; border-bottom: 1px solid #e5e7eb;">思考过程</summary>
  <div style="padding: 12px; background: #ffffff; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 16px; line-height: 1.5; color: #4b5563; white-space: pre-wrap;">${cleanThinkContent}</div></details>`
  })

  // 如果是流式消息，添加实时更新的标识
  if (isStreaming.value) {
    console.log('渲染流式内容:', {
      messageId: props.message.id,
      contentLength: content.length,
      preview: content,
      timestamp: props.message.lastUpdated || Date.now()
    })
  }

  return formattedText
})

// 方法
const formatTime = (timestamp: number): string => {
  const date = new Date(timestamp)
  const now = new Date()
  const diff = now.getTime() - date.getTime()

  if (diff < 60000) {
    // 小于1分钟
    return '刚刚'
  } else if (diff < 3600000) {
    // 小于1小时
    return `${Math.floor(diff / 60000)}分钟前`
  } else if (diff < 86400000) {
    // 小于1天
    return `${Math.floor(diff / 3600000)}小时前`
  } else {
    return date.toLocaleDateString('zh-CN', {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    })
  }
}

const getWorkflowStatusClass = (status: WorkflowRunningStatus): string => {
  const classes = {
    running: 'bg-blue-100 text-blue-800',
    succeeded: 'bg-green-100 text-green-800',
    failed: 'bg-red-100 text-red-800',
    stopped: 'bg-gray-100 text-gray-800'
  }
  return classes[status] || 'bg-gray-100 text-gray-800'
}

const getWorkflowStatusText = (status: WorkflowRunningStatus): string => {
  const texts = {
    running: '运行中',
    succeeded: '成功',
    failed: '失败',
    stopped: '已停止'
  }
  return texts[status] || status
}

const getNodeStatusClass = (status: string): string => {
  if (!status) return 'text-blue-600'
  return status === 'succeeded'
    ? 'text-green-600'
    : status === 'failed'
      ? 'text-red-600'
      : 'text-blue-600'
}

const copyMessage = async (): Promise<void> => {
  try {
    await navigator.clipboard.writeText(props.message.content)
    emit('copy', props.message.content)
  } catch (error) {
    console.error('复制失败:', error)
  }
}

const regenerateMessage = (): void => {
  emit('regenerate', props.message.id)
}

const handleDirectFeedback = async (rating: 'like' | 'dislike'): Promise<void> => {
  console.log('点击反馈按钮:', rating, '消息ID:', props.message.id)

  if (feedbackLoading.value) {
    console.log('反馈正在加载中，忽略点击')
    return
  }

  feedbackLoading.value = true
  console.log('开始处理反馈，设置加载状态为true')

  try {
    const feedbackData: Feedbacktype = {
      rating,
      content: null
    }

    console.log('准备触发反馈事件:', feedbackData)

    // 触发事件
    emit('feedback', props.message.id, feedbackData)
    console.log('反馈事件已触发')

    // 等待一小段时间让父组件处理
    await new Promise((resolve) => setTimeout(resolve, 1500))

    console.log(`反馈提交成功: ${rating}`)
  } catch (error) {
    console.error('反馈提交失败:', error)
    // 可以在这里添加错误提示
  } finally {
    feedbackLoading.value = false
    console.log('反馈处理完成，重置加载状态')
  }
}

const previewImage = (url: string) => {
  // 可以实现图片预览功能
  window.open(url, '_blank')
}

// 添加文件处理方法
const getFileName = (file: any) => {
  return file.name || file.id || file.upload_file_id || '未知文件'
}

const getFileExtension = (file: any) => {
  if (file.name) {
    const ext = file.name.split('.').pop()
    return ext || ''
  }
  if (file.type) {
    // 从MIME类型推断扩展名
    const mimeToExt: Record<string, string> = {
      'application/pdf': 'pdf',
      'application/msword': 'doc',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
      'text/plain': 'txt',
      'image/jpeg': 'jpg',
      'image/png': 'png',
      'image/gif': 'gif'
    }
    return mimeToExt[file.type] || ''
  }
  return ''
}

const formatFileSize = (bytes: number) => {
  if (!bytes || bytes === 0) return ''
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const downloadFile = (file: any) => {
  if (file.url) {
    const link = document.createElement('a')

    link.href = import.meta.env.VITE_API_DOWNLOAD_URL + file.url

    link.download = getFileName(file)
    console.log('link.download:', link.download)
    link.target = '_blank'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
}

// 切换工作流展开状态
const toggleWorkflowExpanded = () => {
  workflowExpanded.value = !workflowExpanded.value
}

// 添加文件类型判断方法
const getFileType = (fileName: string) => {
  if (!fileName) return 'default'

  const ext = fileName.split('.').pop()?.toLowerCase()
  if (!ext) return 'default'

  // 文档类型
  if (['pdf'].includes(ext)) return 'pdf'
  if (['doc', 'docx'].includes(ext)) return 'doc'
  if (['xls', 'xlsx'].includes(ext)) return 'excel'
  if (['ppt', 'pptx'].includes(ext)) return 'ppt'
  if (['txt', 'md', 'rtf'].includes(ext)) return 'txt'

  // 压缩文件
  if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) return 'zip'

  // 媒体文件
  if (['mp3', 'wav', 'flac', 'aac', 'm4a'].includes(ext)) return 'audio'
  if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'].includes(ext)) return 'video'

  // 代码文件
  if (
    [
      'js',
      'ts',
      'jsx',
      'tsx',
      'vue',
      'html',
      'css',
      'scss',
      'py',
      'java',
      'cpp',
      'c',
      'php',
      'go',
      'rs'
    ].includes(ext)
  )
    return 'code'

  return 'default'
}
</script>

<style scoped>
.chat-message {
  @apply flex gap-3 mb-6;
  align-items: flex-start;
}

.user-message {
  @apply flex-row-reverse;
}

.user-message .message-content {
  @apply items-end;
  width: auto;
  max-width: 70%;
}

.user-message .message-bubble {
  @apply bg-blue-500 text-white ml-auto;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  width: auto;
  max-width: fit-content;
}

.user-message .sender-name {
  @apply text-blue-100 text-right;
}

.user-message .message-text {
  @apply text-white;
}

.avatar {
  @apply flex-shrink-0 w-10 h-10 rounded-full flex  shadow-lg;
}

.user-avatar {
  @apply text-white;
}

.ai-avatar {
  @apply text-white;
  background: rgb(255, 234, 213);
  border-radius: 9999px;
}
.message-content {
  @apply flex flex-col;
  flex: 0 1 auto;
  width: 100%;
}

.message-bubble {
  @apply rounded-2xl px-4 py-3 shadow-sm break-words;
  background: white;
  border: 1px solid #f1f5f9;
  width: 100%;
  overflow-wrap: break-word;
}

.sender-name {
  @apply text-sm font-medium text-gray-700 mb-2 px-1;
}

.message-files {
  @apply space-y-2 mb-3;
}

.file-attachment {
  @apply inline-block mr-2 mb-2;
}

.attached-image {
  @apply max-w-xs rounded-lg cursor-pointer hover:opacity-90 transition-opacity;
}

.file-item {
  @apply flex items-center gap-3 p-3 bg-white/10 rounded-lg border border-white/20 text-sm backdrop-blur-sm;
  transition: all 0.2s ease;
}

.file-item:hover {
  @apply bg-white/20 border-white/30 transform scale-[1.02];
}

.user-message .file-item {
  @apply bg-white/10 border-white/20 text-white;
}

.user-message .file-item:hover {
  @apply bg-white/20 border-white/30;
}

.user-message .file-icon-wrapper {
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.agent-thoughts {
  @apply space-y-3 mb-4 p-3 bg-blue-50 rounded-lg border border-blue-200;
  margin: 0 -16px 16px -16px;
}

.thought-item {
  @apply space-y-2;
}

.thought-header {
  @apply flex items-center gap-2 text-sm font-medium text-blue-800 mb-2;
}

.thought-tool {
  @apply font-medium text-amber-800;
}

.thought-position {
  @apply text-amber-600;
}

.thought-content {
  @apply text-sm text-gray-700 pl-2 border-l-2 border-amber-300;
}

.thought-input,
.thought-observation {
  @apply text-sm text-gray-600;
}

.thought-files {
  @apply flex gap-3 flex-wrap mt-3;
}

.thought-image {
  @apply w-20 h-20 object-cover rounded-lg cursor-pointer border border-blue-200 hover:border-blue-400 transition-all duration-200;
}

.thought-image:hover {
  @apply transform scale-105 shadow-md;
}

.thought-file {
  @apply flex items-center gap-2 p-2 bg-white rounded-lg border border-blue-200;
}

.workflow-status {
  @apply p-3 bg-gray-50 rounded-lg;
}

.status-header {
  @apply flex items-center gap-2 mb-2;
}

.status-badge {
  @apply px-2 py-1 rounded-full text-xs font-medium;
}

.workflow-id {
  @apply text-xs text-gray-500 font-mono;
}

.workflow-tracing {
  @apply space-y-1;
}

.trace-item {
  @apply p-3 bg-white rounded-lg border border-gray-200;
}

.trace-node {
  @apply flex items-center justify-between;
}

.trace-node-info {
  @apply flex flex-col;
}

.node-type {
  @apply font-medium text-gray-900 text-sm;
}

.node-id {
  @apply text-xs text-gray-500 mt-1;
}

.node-status {
  @apply flex items-center gap-1 text-xs font-medium;
}

.citations {
  @apply p-3 bg-blue-50 rounded-lg border border-blue-200 mt-3;
}

.citation-header {
  @apply flex items-center gap-2 font-medium text-blue-800 mb-2;
}

.citation-list {
  @apply space-y-2;
}

.citation-item {
  @apply p-2 bg-white rounded text-sm border border-blue-100;
}

.citation-content {
  @apply text-gray-800 mb-1 break-words leading-relaxed;
}

.citation-meta {
  @apply text-xs text-gray-500 flex items-center gap-2;
}

.annotation {
  @apply p-3 bg-purple-50 rounded-lg border border-purple-200 mt-3;
}

.annotation-header {
  @apply flex items-center gap-2 font-medium text-purple-800 mb-2;
}

.annotation-author {
  @apply text-sm text-purple-600;
}

.annotation-content {
  @apply text-gray-800;
}

.suggested-questions {
  @apply p-3 bg-green-50 rounded-lg mt-3;
}

.suggestions-header {
  @apply font-medium text-green-800 mb-2;
}

.suggestions-list {
  @apply space-y-2;
}

.suggestion-btn {
  @apply block w-full text-left p-2 bg-white hover:bg-green-100 rounded border border-green-200 text-sm transition-colors;
}

.message-text {
  @apply text-gray-900 leading-relaxed;
}

.user-message .message-text {
  @apply text-white;
}

.message-text :deep(strong) {
  @apply font-semibold;
}

.message-text :deep(em) {
  @apply italic;
}

.message-text :deep(code) {
  @apply px-1 py-0.5 rounded text-sm font-mono;
  background-color: rgba(0, 0, 0, 0.1);
}

.user-message .message-text :deep(code) {
  background-color: rgba(255, 255, 255, 0.2);
}

.message-text :deep(pre) {
  @apply p-3 rounded-lg overflow-x-auto my-2;
  background-color: rgba(0, 0, 0, 0.05);
}

.user-message .message-text :deep(pre) {
  background-color: rgba(255, 255, 255, 0.1);
}

.message-text :deep(pre code) {
  @apply bg-transparent p-0;
}

.message-meta {
  @apply flex items-center justify-between text-xs text-gray-500 mb-2 px-1;
}

.more-info {
  @apply flex gap-3;
}

.token-count,
.latency {
  @apply px-2 py-1 bg-gray-100 rounded;
}

.feedback-section {
  @apply mt-3 pt-3 border-t border-gray-200;
}

.current-feedback {
  @apply flex items-center justify-between text-sm;
}

.edit-feedback-btn {
  @apply text-blue-600 hover:text-blue-800 text-xs;
}

.feedback-buttons {
  @apply flex gap-2 mt-2;
}

.feedback-btn {
  @apply p-2 rounded-lg border transition-colors;
}

.like-btn {
  @apply border-green-200 text-green-600 hover:bg-green-50;
}

.dislike-btn {
  @apply border-red-200 text-red-600 hover:bg-red-50;
}

.feedback-form {
  @apply space-y-3 p-3 bg-gray-50 rounded-lg;
}

.feedback-rating {
  @apply flex gap-2;
}

.rating-option {
  @apply px-3 py-2 rounded border transition-colors;
}

.rating-option.active {
  @apply bg-blue-500 text-white border-blue-500;
}

.feedback-textarea {
  @apply w-full p-2 border border-gray-300 rounded resize-none focus:outline-none focus:ring-2 focus:ring-blue-500;
}

.feedback-actions {
  @apply flex gap-2;
}

.submit-btn {
  @apply px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors;
}

.cancel-btn {
  @apply px-4 py-2 border border-gray-300 text-gray-700 rounded hover:bg-gray-50 transition-colors;
}

.message-actions {
  @apply flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity mt-2;
}

.action-btn {
  @apply p-2 rounded-lg hover:bg-gray-200 text-gray-500 hover:text-gray-700 transition-colors;
}

/* 流式消息的特殊样式 */
.message-text.streaming {
  position: relative;
}

.message-text.streaming::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1.2em;
  background-color: #3b82f6;
  margin-left: 2px;
  animation: blink 1s infinite;
  vertical-align: text-bottom;
}

/* 优化流式文本的显示效果 */
.message-text.streaming :deep(*) {
  animation: fadeIn 0.3s ease-in;
}

.thinking-dots {
  @apply text-gray-500 italic;
}

.thinking-dots .dots {
  animation: thinking 1.5s infinite;
}

@keyframes thinking {
  0%,
  20% {
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

@keyframes blink {
  0%,
  50% {
    opacity: 1;
  }
  51%,
  100% {
    opacity: 0;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 响应文件样式优化 */
.response-files {
  @apply mt-4 border border-gray-200 rounded-xl overflow-hidden bg-white shadow-sm;
  margin: 16px -16px -12px -16px;
}

.files-header {
  @apply flex items-center gap-3 px-4 py-3 bg-gradient-to-r from-gray-50 to-gray-100 border-b border-gray-200 font-medium text-gray-700 text-sm;
}

.files-header svg {
  @apply w-4 h-4 text-blue-500;
}

.files-list {
  @apply divide-y divide-gray-100;
}

.response-file-item {
  @apply flex items-center gap-4 p-4 hover:bg-gray-50 transition-all duration-200;
}

.response-file-item:hover {
  @apply transform translate-x-1 bg-gradient-to-r from-blue-50/50 to-transparent;
}

.file-main-info {
  @apply flex items-center gap-4 flex-1 min-w-0;
}

.file-icon {
  @apply flex-shrink-0 w-10 h-10 flex items-center justify-center;
}

.file-preview-image {
  @apply w-12 h-12 object-cover rounded-lg cursor-pointer hover:opacity-80 transition-all duration-200 border border-gray-200;
}

.file-preview-image:hover {
  @apply transform scale-105 shadow-md;
}

.file-details {
  @apply flex-1 min-w-0;
}

.file-title {
  @apply font-medium text-gray-900 text-sm truncate;
}

.file-meta {
  @apply flex items-center gap-2 text-xs text-gray-500 mt-1;
}

.file-extension {
  @apply px-2 py-1 bg-blue-100 text-blue-700 rounded-md text-xs font-medium uppercase;
}

.file-divider {
  @apply text-gray-400;
}

.file-size {
  @apply text-gray-500 font-mono;
}

.file-actions {
  @apply flex gap-2 flex-shrink-0;
}

.file-action-btn {
  @apply p-2 rounded-lg hover:bg-blue-100 text-gray-500 hover:text-blue-600 transition-all duration-200;
}

.file-action-btn:hover {
  @apply transform scale-110;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .message-content {
    @apply max-w-none;
  }

  .message-bubble {
    @apply rounded-xl px-3 py-2;
  }

  .attached-image {
    @apply max-w-full;
  }

  .file-icon-wrapper {
    @apply w-7 h-7;
  }

  .file-icon {
    @apply w-5 h-5;
  }

  .response-file-item {
    @apply gap-3 p-3;
  }

  .file-main-info {
    @apply gap-3;
  }

  .file-preview-image {
    @apply w-10 h-10;
  }

  .file-title {
    @apply text-xs;
  }

  .file-meta {
    @apply text-xs;
  }
}

/* 新的工作流状态样式 */
.workflow-status-section {
  @apply mb-3;
  margin: -12px -16px 12px -16px;
}

.workflow-button {
  @apply cursor-pointer p-3 bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-all duration-200;
}

.workflow-button-content {
  @apply flex items-center gap-3;
}

.workflow-icon {
  @apply flex-shrink-0 w-4 h-4 text-green-600;
}

.workflow-text {
  @apply text-sm font-medium text-gray-800;
}

.workflow-status-badge {
  @apply px-2 py-1 rounded-full text-xs font-medium ml-auto;
}

.workflow-status-badge.bg-green-100 {
  background-color: #dcfce7;
  color: #166534;
}

.workflow-chevron {
  @apply w-4 h-4 text-gray-600 transition-transform duration-200;
}

.workflow-details {
  @apply mt-3 p-3 bg-gray-50 border border-gray-200 rounded-lg;
}

.tracing-header {
  @apply flex items-center gap-2 text-sm font-medium text-gray-700 mb-3;
}

.tracing-list {
  @apply space-y-2;
}

.trace-item {
  @apply p-3 bg-white rounded-lg border border-gray-200;
}

.trace-node {
  @apply flex items-center justify-between;
}

.trace-node-info {
  @apply flex flex-col;
}

.node-type {
  @apply font-medium text-gray-900 text-sm;
}

.node-id {
  @apply text-xs text-gray-500 mt-1;
}

.node-status {
  @apply flex items-center gap-1 text-xs font-medium;
}

/* 查看更多节点指示器样式 */
.more-nodes-indicator {
  @apply mt-2 pt-2 border-t border-gray-200;
}

.more-nodes-content {
  @apply flex items-center justify-center gap-2 text-sm text-gray-500 py-2 cursor-pointer hover:text-gray-700 transition-colors;
}

.more-text {
  @apply font-medium;
}

/* 文件图标样式优化 */
.file-icon-wrapper {
  @apply flex-shrink-0 w-8 h-8 flex items-center justify-center rounded-lg;
  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  border: 1px solid #dee2e6;
}

.file-icon {
  @apply w-10 h-10 transition-all duration-200;
}

/* PDF 文件图标 */
.pdf-icon {
  @apply text-red-600;
  background: linear-gradient(135deg, #fee2e2, #fecaca);
  border-radius: 6px;
  padding: 2px;
}

/* Word 文档图标 */
.word-icon {
  @apply text-blue-700;
  background: linear-gradient(135deg, #dbeafe, #bfdbfe);
  border-radius: 6px;
  padding: 2px;
}

/* Excel 文件图标 */
.excel-icon {
  @apply text-green-700;
  background: linear-gradient(135deg, #dcfce7, #bbf7d0);
  border-radius: 6px;
  padding: 2px;
}

/* PowerPoint 文件图标 */
.powerpoint-icon {
  @apply text-orange-600;
  background: linear-gradient(135deg, #fed7aa, #fdba74);
  border-radius: 6px;
  padding: 2px;
}

/* 文本文件图标 */
.text-icon {
  @apply text-gray-600;
  background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
  border-radius: 6px;
  padding: 2px;
}

/* 压缩文件图标 */
.archive-icon {
  @apply text-purple-600;
  background: linear-gradient(135deg, #ede9fe, #ddd6fe);
  border-radius: 6px;
  padding: 2px;
}

/* 音频文件图标 */
.audio-icon {
  @apply text-pink-600;
  background: linear-gradient(135deg, #fce7f3, #fbcfe8);
  border-radius: 6px;
  padding: 2px;
}

/* 视频文件图标 */
.video-icon {
  @apply text-indigo-600;
  background: linear-gradient(135deg, #e0e7ff, #c7d2fe);
  border-radius: 6px;
  padding: 2px;
}

/* 代码文件图标 */
.code-icon {
  @apply text-emerald-600;
  background: linear-gradient(135deg, #d1fae5, #a7f3d0);
  border-radius: 6px;
  padding: 2px;
}

/* 默认文件图标 */
.default-icon {
  @apply text-slate-600;
  background: linear-gradient(135deg, #f1f5f9, #e2e8f0);
  border-radius: 6px;
  padding: 2px;
}

/* AI思考过程折叠块样式 */
:deep(.think-collapse) {
  margin: 10px 0;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
  background: #ffffff;
  transition: all 0.2s ease;
}

:deep(.think-collapse:hover) {
  border-color: #d1d5db;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

:deep(.think-collapse summary) {
  background: linear-gradient(135deg, #f8fafc, #f1f5f9);
  padding: 10px 14px;
  cursor: pointer;
  font-weight: 500;
  color: #374151;
  border-bottom: 1px solid #e5e7eb;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: background 0.2s ease;
  user-select: none;
}

:deep(.think-collapse summary:hover) {
  background: linear-gradient(135deg, #f1f5f9, #e2e8f0);
}

:deep(.think-collapse summary::-webkit-details-marker) {
  display: none;
}

:deep(.think-collapse summary::before) {
  content: '▶';
  display: inline-block;
  width: 12px;
  transition: transform 0.2s ease;
  color: #6b7280;
  font-size: 11px;
}

:deep(.think-collapse[open] summary::before) {
  transform: rotate(90deg);
}

:deep(.think-collapse > div) {
  padding: 14px;
  background: #ffffff;
  font-family: 'SF Mono', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
  font-size: 13px;
  line-height: 1.6;
  color: #4b5563;
  white-space: pre-wrap;
  word-wrap: break-word;
  border-top: 1px solid #f3f4f6;
}

:deep(.think-collapse > div::selection) {
  background: #dbeafe;
}
</style>
